#include "Device.h"
#include "VideoDecoder.h"

void Device::Init(const std::string &rtsp_url, const std::string &device_id, const int32_t gpu_idx, const int32_t cpu_core_idx)
{
    _gpu_idx = gpu_idx;
    _core_idx = cpu_core_idx;

    _fps_decoder = std::make_shared<FpsCalculator>();
    _fps_decoder->Init(100, fmt::format("{}_decoder", device_id), true);
    _fps_process = std::make_shared<FpsCalculator>();
    _fps_process->Init(50, fmt::format("{}_process", device_id), true);

    _rtsp_url = rtsp_url;
    _device_id = device_id;

    // _circular_queue.set_capacity(10);
    _video_decoder = std::make_shared<VideoDecoder>();
    _video_decoder->Init(rtsp_url, _gpu_idx, cpu_core_idx);
    _video_decoder->SetImageCallback([this](std::shared_ptr<ImageInfo> image) {
        _fps_decoder->Add();
        // std::scoped_lock<std::mutex> g(_queue_mtx);
        // _circular_queue.push_back(image);

        std::shared_ptr<ImageInfo> dummy;

        while (!_circular_queue.push(image))
        {
            _circular_queue.pop(dummy);
        }
    });

    std::string push_url = fmt::format("rtsp://192.168.112.126:554/Streaming/Channels/{}", device_id);

    _video_encoder = std::make_shared<VideoEncoder>();
    _video_encoder->Init(25, true, push_url, gpu_idx, cpu_core_idx);
}

void Device::Start()
{
    _start = true;
    _work_thread = std::make_shared<std::thread>([this]() { WorkThread(); });

    _video_decoder->Start();
    _video_encoder->Start();
}

void Device::Stop()
{
    _start = false;
    if (_work_thread)
    {
        _work_thread->join();
        _work_thread = nullptr;
    }
    _video_decoder->Stop();

    _video_encoder->Stop();
}

void Device::SetOutDir(const std::string &dir)
{
    _out_dir = dir;
}

int Device::ReconnectTimes()
{
    if (_video_decoder)
        return _video_decoder->ReconnectTimes();
    else
        return 0;
}

std::string Device::DeviceID()
{
    return _device_id;
}

void Device::WorkThread()
{
    // 处理线程和解码线程使用同样的gpu
    cudaSetDevice(_gpu_idx);
    cv::cuda::setDevice(_gpu_idx);

    while (_start)
    {
        if (_core_idx > -1)
        {
            cpu_set_t cpuset;
            CPU_ZERO(&cpuset);
            CPU_SET(_core_idx, &cpuset);
            pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
        }

        std::shared_ptr<ImageInfo> image = nullptr;
        {
            // std::scoped_lock<std::mutex> g(_queue_mtx);
            // if (!_circular_queue.empty())
            // {
            //     image = _circular_queue.front();
            //     _circular_queue.pop_front();
            // }

            _circular_queue.pop(image);
        }

        if (image)
        {
            _fps_process->Add();

            if (image->index % 100 == 0)
            {
                auto current = fmt::localtime(std::time(nullptr));
                auto text = fmt::format("{:%Y-%m-%d-%H-%M-%S}", current);
                auto filename = fmt::format("{}_{}_{}.jpg", _device_id, image->index, text);

                auto filepath = std::filesystem::path(_out_dir) / filename;

                // cv::Mat mat = image->image;
                cv::Mat mat;
                image->image.download(mat);

                // auto mat = cv::Mat(image->height, image->width, CV_8UC3, image->data.get());

                // {
                //     int fontFace = cv::FONT_HERSHEY_SIMPLEX; // 字体类型
                //     double fontScale = 2.0; // 字体大小
                //     cv::Scalar color(0, 0, 255); // 颜色 (BGR格式，红色)
                //     int thickness = 3; // 线条粗细
                //     int lineType = cv::LINE_AA; // 线条类型（抗锯齿）

                //     // 文字位置（左下角坐标）
                //     cv::Point position(100, 250);
                //     // 绘制文字
                //     cv::putText(mat, text, position, fontFace, fontScale, color, thickness, lineType);
                // }

                {
                    auto timestamp = std::chrono::system_clock::to_time_t(image->time);
                    auto begin = fmt::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(timestamp));

                    int fontFace = cv::FONT_HERSHEY_SIMPLEX; // 字体类型
                    double fontScale = 2.0; // 字体大小
                    cv::Scalar color(50, 50, 200); // 颜色 (BGR格式，红色)
                    int thickness = 3; // 线条粗细
                    int lineType = cv::LINE_AA; // 线条类型（抗锯齿）

                    cv::Point position(150, 500);
                    // 绘制文字
                    cv::putText(mat, text, position, fontFace, fontScale, color, thickness, lineType);
                }



                std::vector<int> compression_params;
                compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
                compression_params.push_back(95); // 0-100, 100最高质量
                cv::imwrite(filepath.string(), mat, compression_params);

                // SPDLOG_INFO(filepath);
            }
           else
            {
                // TODO: 数据处理
                // std::this_thread::sleep_for(100ms);

                if (_video_encoder) {
                _video_encoder->AddImage(image);
                }
            }
        }
        else
        {
            std::this_thread::sleep_for(100ms);
        }
    }
}
